﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Licensed MIT: http://www.opensource.org/licenses/mit-license.php

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Dynamic;

namespace DNA.Mvc.Community.Data.Entity
{
    public class ThreadRepository : GenericForumRepository<Thread>, IThreadRepository
    {
        public ThreadRepository() : base() { }

        public ThreadRepository(ForumDb context) : base(context) { }

        public void Move(int threadID, int forumID)
        {
            var thread = Find(threadID);
            var forums = Context.Set<Forum>();
            var forum =forums.Find(forumID);
            
            if ((thread != null) && (forum != null))
            {
                var orgForumID = thread.ForumID;
                thread.Forum.TotalPosts -= thread.TotalPosts;
                thread.Forum = forum;
                forum.TotalPosts += thread.TotalPosts;

                if (thread.LastPost!=null)
                {
                    var posted = thread.LastPost.Posted;
                    if (forum.LastPostID == 0)
                    {
                        forum.LastPostID = thread.LastPostID.Value;
                        Context.Entry<Forum>(forum).State = System.Data.EntityState.Modified;
                    }
                    else
                    {
                        var lastPost = Context.Set<Post>().Find(forum.LastPostID);
                        if (lastPost != null)
                        {
                            if (posted > lastPost.Posted)
                            {
                                forum.LastPostID = lastPost.ID;
                                Context.Entry<Forum>(forum).State = System.Data.EntityState.Modified;
                            }
                        }
                    }
                }
                

                Update(thread);
            }
        }

        public IQueryable<Thread> GetUserThreads(string username, string sortby, SortingOrders order, int pageIndex, int pageSize, out int totalRecords)
        {
            var skips = pageIndex * pageSize;
            totalRecords = dbSet.Count(t => t.Author.Equals(username));
            var query = DbSet.Where(t => t.Author.Equals(username) && !t.IsDeleted);
            
            if (string.IsNullOrEmpty(sortby))
            {
                query=query.OrderByDescending(t => t.Posted);
            }
            else
            {
                if (order == SortingOrders.Asc)
                    query = query.OrderBy(sortby);
                else
                    query = query.OrderBy(sortby + " desc");
            }
            
            if (skips > 0)
                return query.Skip(skips).Take(pageSize);
            else
                return query.Take(pageSize);
        }

        public IQueryable<Thread> GetModeratedThreads(int forumID, int pageIndex, int pageSize, out int totalRecords)
        {
            var skips = pageIndex * pageSize;
            totalRecords = dbSet.Count(t => t.ForumID == forumID && !t.IsApproved);
            var query = DbSet.Where(t => t.ForumID == forumID && !t.IsApproved).OrderByDescending(t => t.Posted);
            if (skips > 0)
                return query.Skip(skips).Take(pageSize);
            else
                return query.Take(pageSize);
        }

        public IQueryable<Thread> GetPinnedThreads(int forumID)
        {
            return DbSet.Where(t => t.ForumID == forumID && t.IsApproved && t.IsPinned).OrderByDescending(t => t.Posted);
        }

        public void Read(int id)
        {
            var thread =DbSet.Find(id);
            thread.TotalReads++;
            if (IsOwnContext) Context.SaveChanges();
        }

        public void Pin(int id, bool value)
        {
            var thread = DbSet.Find(id);
            thread.IsPinned = true;
            if (IsOwnContext) Context.SaveChanges();
        }

        public void Lock(int id, bool value)
        {
            var thread = DbSet.Find(id);
            thread.IsLocked = value;
            if (IsOwnContext) Context.SaveChanges();
        }

        public Thread Next(int forumID,int id)
        {
            return DbSet.Where(t => t.ForumID == forumID && t.ID > id && t.IsApproved ).FirstOrDefault();  
           
        }

        public Thread Prev(int forumID, int id)
        {
            return DbSet.Where(t => t.ForumID == forumID && t.ID < id && t.IsApproved).FirstOrDefault();  
        }
    }
}
